Skip to content

Implement Minnesota Child Care Assistance Program (CCAP)#8637

Open
hua7450 wants to merge 10 commits into
PolicyEngine:mainfrom
hua7450:mn-ccap
Open

Implement Minnesota Child Care Assistance Program (CCAP)#8637
hua7450 wants to merge 10 commits into
PolicyEngine:mainfrom
hua7450:mn-ccap

Conversation

@hua7450

@hua7450 hua7450 commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements Minnesota's Child Care Assistance Program (CCAP) in PolicyEngine — a provider-rate reimbursement subsidy computed per child as the lesser of the provider's charge or the state maximum rate, minus the biweekly parent fee. Administered by the Minnesota Department of Children, Youth, and Families (DCYF), which took CCAP over from the Department of Human Services (DHS) in 2024.

Closes #8636

Regulatory Authority

Program Overview

  • Three subprograms, all sharing the same benefit/rate/copay mechanics and differing only in entry income limit and funding: MFIP/DWP Child Care (67% SMI entry), Transition Year (families who left MFIP within the prior year), and Basic Sliding Fee (47% SMI entry). Modeled via a single income-limit switch rather than separate benefit formulas.
  • Income limits are defined as a percentage of State Median Income by household size. These reconcile exactly with the federal hhs_smi variable × {47% / 67% / 85%} (verified to the dollar against DHS-6413N: 2-person 47% = $46,022; 3-person 67% = $81,042; 4-person 85% = $122,398), so the implementation reuses hhs_smi rather than introducing a separate Minnesota SMI variable.

Eligibility

Requirement Source How Modeled
Family has ≥1 eligible child in care Minn. Rules 3400.0110; manual §6.x mn_ccap_eligible aggregates mn_ccap_eligible_child over the SPM unit
Child under 13 (under 15 if disabled) Minn. Stat. 142E.01/142E.11 age_threshold/child.yaml (13) + disabled_child.yaml (15) in mn_ccap_eligible_child
Child is a dependent program rules is_tax_unit_dependent in mn_ccap_eligible_child
Child is a citizen / qualified noncitizen 45 CFR 98.20; 8 USC 1641 reuse federal is_ccdf_immigration_eligible_child
Parent(s) in an authorized activity manual §4.6.1/§4.6.3; Minn. Stat. 142E.12 mn_ccap_activity_eligible (see below)
Family assets ≤ $1,000,000 manual §4.12; Minn. Rules 3400.0170 reuse federal is_ccdf_asset_eligible
Income test (% of SMI) manual §6.3; DHS-6413N p.5 mn_ccap_income_eligible (SMI test reusing hhs_smi)

Authorized activity (mn_ccap_activity_eligible; manual §4.6.1, §4.6.3; Minn. Stat. 142E.12 subd. 1(b)): at least one caretaker must be in an authorized activity — employed an average of ≥ 20 hrs/week, or enrolled as a full-time student (education is itself an authorized activity under §4.6.6.9, with no work-hours floor). In a two-caretaker family the other caretaker must also be active or "unable to provide care" — modeled via is_disabled, is_incapable_of_self_care, is_incarcerated (house arrest), and out-of-home/residential care-facility status. MFIP/DWP families meet the requirement categorically through their Employment Plan (is_tanf_enrolled), and families experiencing homelessness are exempt from the activity requirement (§4.6.9), modeled via is_homeless — we don't track the manual's ~3-month exemption window, so the exemption applies for the full period. The meets_ccdf_activity_test input covers approved activities we don't derive directly (job search, education/training programs, temporary leave) and the applicable-minimum-wage component.

Income

Income base = annual gross income after allowable deductions, used for both the eligibility test and the copay band lookup (manual §6.3, §6.6; Minn. Rules 3400.0170 subp. 4; Minn. Stat. 256P.06).

  • Counted earned income (gross, before payroll deductions) — wages/salary incl. overtime and bonuses, paid vacation/sick leave, tips, commissions, severance, royalties, honoraria, taxable allowances, incentive payments, military pay (combat-zone pay excluded). Parameter: income/countable_income/earned.yaml.
  • Self-employment is counted separately and floored per person (income/countable_income/self_employment_sources.yaml): a net business loss may offset other self-employment income but cannot reduce wages or unearned income (Minn. Rules 3400.0170 subp. 4; manual §6.15.6), so mn_ccap_gross_earned_income applies max_(self_employment, 0) per person before adding it to wages.
  • A child's earned income is excluded (manual §6.6.1 / Exempt Earned Income chart §16.27): mn_ccap_gross_earned_income subtracts the earnings of household members under 18 (is_child). This is a simplification — the manual additionally counts a non-student minor's earnings and a dependent post-secondary student's earnings, which we don't separately track.
  • Counted unearned income (exhaustive "includes only" list) — cash assistance (MFIP cash, MFIP Housing Assistance Grant, DWP, MSA, GA, RCA), interest/dividends, capital gains on real property, contract-for-deed above principal+interest, trust income (excl. special/supplemental needs trusts), family-loan interest, unemployment insurance, disability insurance, workers' comp, retirement/pension/veteran benefits, child/spousal support not assigned to the state, RSDI gross, cash prizes/winnings, taxable military entitlements. Parameter: income/countable_income/unearned.yaml. Income types without a PolicyEngine variable are listed as inline comments.
  • Allowable deductions (manual §6.18, verified; Minn. Rules 3400.0170 subp. 6a): child support paid out-of-household; spousal support paid out-of-household; medical/dental/vision insurance premiums paid by family members; the un-reimbursed portion of an insurance premium for Medical Assistance recipients; expenditures necessary to secure payment of unearned income. Parameter: income/deductions/sources.yaml; applied as mn_ccap_countable_income = max_(gross − deductions, 0).

Benefit Calculation

Per eligible child:

subsidy = max_(min_(actual_expenses, max_rate × (1 + quality_differential)) − biweekly_copay, 0)

summed across eligible children. Actual expenses come from the federal spm_unit_pre_subsidy_childcare_expenses (RI/MA/CO precedent). The parent pays any provider charge above the maximum, plus the copay (manual §9.9; Minn. Stat. 142E.17 subd. 1(e),(i)).

  • Maximum rate keyed by County (87 counties) × provider type (Family Child Care | Child Care Center) × age group (Infant | Toddler | PreSchool | School Age) × rate unit. License-exempt programs are paid at the licensed-center rate for the same age group; LNL (Legal Non-Licensed) providers use their own hourly column. Parameters: rates/{weekly,full_day,hourly,lnl_hourly}.yaml.
  • Rate unit (§9.9, single provider): weekly if scheduled/authorized > 35 hrs/week; full-day if ≤ 35 hrs/week and > 5 hrs/day; hourly if ≤ 35 hrs/week and ≤ 5 hrs/day. LNL providers are forced to hourly. Variable: mn_ccap_rate_unit; parameters: rate_unit/{weekly,daily}_hours_threshold.yaml.
  • Monthly conversion & statutory caps (Minn. Stat. 142E.17 subd. 1(f), 2(b); manual §9.9): weekly max × (weeks/12); daily and hourly billing are converted to a monthly maximum subject to the statutory ceilings — payment for one day of care cannot exceed the daily rate, payment for one week cannot exceed the weekly rate, and legal non-licensed payment is capped at 10 hours/day and 50 hours/week. Parameters: rates/lnl_max_daily_hours.yaml (10), rates/lnl_max_weekly_hours.yaml (50).
  • Quality differential applied as a multiplier on the standard maximum rate, capped at the provider's charge: ×1.15 for accredited/credentialed or 3-star Parent Aware providers, ×1.20 for 4-star Parent Aware (manual §9.24.9/§9.24.12; Minn. Stat. 142E.17 subd. 4–5). Parameter: quality_differential.yaml.
  • Copay (parent fee) looked up by household size (2–13) × annual-income band → flat biweekly dollar amount, then converted to monthly (DHS-6413N pp.6–11; Minn. Stat. 142E.15). $0 in the lowest band, rising with income. Parameters: copay/biweekly/size_2.yamlsize_13.yaml; variable: mn_ccap_copay.

Source Verification

Every published dollar value was verified against the official PDFs:

  • DHS-6441F provider rates — all county × provider-type × age × rate-unit values (incl. LNL) checked against the form; full match.
  • DHS-6413N copay schedule — all 12 household-size schedules × income bands checked; full match. Entrance/exit dollar levels reconcile to hhs_smi × {47% / 67% / 85%}.
  • Aug 2025 CCAP Policy Manual — eligibility, activity (§4.6), income counting (§6.6/§6.6.1), deductions (§6.18), rate-unit logic and payment caps (§9.9), and quality differentials (§9.24) verified against the implementation.

Not Modeled

What Source Why excluded
Child-support cooperation requirement manual §4.9 Behavioral/administrative status we don't track
Transition Year continuous-eligibility history (67% vs 47% entry) manual §6.3 We don't track prior CCAP eligibility history; defaults to the applicable static limit
Redetermination 67%-of-SMI exit limit manual §6.3 Point-in-time model — we don't track the 12-month redetermination clock
Non-caregiver adult / "CCAP family" scoping manual ch. 5, §6.6.1 Income is summed over the SPM unit; a co-resident non-dependent adult's income may be counted where the manual would exclude it
120-hour/child/biweekly payment cap manual §9.9 Deferred; the per-day and per-week rate caps (subd. 1(f), 2(b)) are now applied, but the 120-hour aggregate cap is not
Registration-fee county-max cap + max 2 fees/child/12 mo manual §9.3.6; DHS-6443D Deferred — the optional input ships now; the county-max table is pending
St. Cloud / Sartell city rate tier DHS-6441F Providers in those two cities use the surrounding county rate (only St. Cloud family-child-care rates differ materially)
Copay cannot increase mid 12-month eligibility period; copay waived by provider/third party manual §6.21 Point-in-time; we don't track the eligibility clock or third-party copay payment
BSF capped allocation → waiting list DHS-4745 We don't model program-capacity waitlists

Verification TODO

  • Confirm the quality differential as a flat ×1.15 / ×1.20 multiplier is acceptable vs transcribing the separate quality-differential rate tables (v1 uses the multiplier per scope decision).
  • CI passes.

Files

policyengine_us/parameters/gov/states/mn/dcyf/ccap/   (32 params)
  age_group/{center_months,family_months}.yaml
  age_threshold/{child,disabled_child}.yaml
  activity/min_weekly_hours.yaml
  copay/biweekly/size_2.yaml … size_13.yaml
  income/countable_income/{earned,unearned}.yaml
  income/deductions/sources.yaml
  income/smi_rate/{entrance_mfip,entrance_other,exit_during_period}.yaml
  quality_differential.yaml
  rate_unit/{weekly,daily}_hours_threshold.yaml
  rates/{weekly,full_day,hourly,lnl_hourly}.yaml
  rates/{lnl_max_daily_hours,lnl_max_weekly_hours}.yaml

policyengine_us/variables/gov/states/mn/dcyf/ccap/   (19 variables)
  mn_ccap.py, mn_child_care_subsidies.py, mn_ccap_countable_income.py,
  mn_ccap_gross_earned_income.py, mn_ccap_gross_unearned_income.py,
  mn_ccap_income_deductions.py, mn_ccap_max_rate.py, mn_ccap_provider_rate.py,
  mn_ccap_provider_type.py, mn_ccap_quality_rating.py, mn_ccap_rate_unit.py,
  mn_ccap_age_group.py, mn_ccap_enrolled.py, mn_ccap_registration_fee.py,
  copay/mn_ccap_copay.py,
  eligibility/{mn_ccap_eligible,mn_ccap_eligible_child,mn_ccap_income_eligible,mn_ccap_activity_eligible}.py

policyengine_us/tests/policy/baseline/gov/states/mn/dcyf/ccap/   (12 test files)
  integration.yaml, mn_ccap_age_group.yaml, mn_ccap_copay.yaml,
  mn_ccap_countable_income.yaml, mn_ccap_max_rate.yaml, mn_ccap_provider_rate.yaml,
  mn_ccap_rate_unit.yaml, mn_child_care_subsidies.yaml,
  eligibility/{mn_ccap_eligible,mn_ccap_eligible_child,mn_ccap_income_eligible,mn_ccap_activity_eligible}.yaml

Test plan

  • 107 MN CCAP tests pass locally (policyengine-core test)
  • CI passes

hua7450 and others added 3 commits June 15, 2026 13:14
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (fbace93) to head (0b8ee01).
⚠️ Report is 23 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##              main     #8637    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            1        19    +18     
  Lines           23       308   +285     
==========================================
+ Hits            23       308   +285     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

hua7450 and others added 7 commits June 15, 2026 15:37
- Model MN CCAP activity-hours requirement (>=20 hr/wk, >=10 FT students) per Minn. Stat. 142E.12 subd.1(b)
- Fix citations: 142E.06->142E.10 subd.1 (income), 142E.01 subd.7->subd.4 (child age), family_months->9502.0315, rate_unit->142E.17 subd.1
- Replace hard-coded 26 with WEEKS_IN_YEAR/2; strip page suffix from reference titles
- Add MN CCAP to programs.yaml; add copay size 7/10 + LNL/exempt/full-day integration tests

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- exit_during_period.yaml: cite DHS-6413N + 45 CFR 98.21(a)(1) for 85% SMI (142E.10 lacks it)
- Document 142E.12 subd.3 education/training pathway as not modeled; pin 142E.12 subd.1(b) ref
- center_months.yaml: align title with 9503.0005 href
- Add inclusive 20-hr activity edge test; fix stale subd.7 comment

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Exclude children's earned income from countable income (manual 6.6.1)
- Activity eligibility: MFIP/DWP categorical, full-time-student education
  pathway, and broaden the "unable to provide care" exemption (manual 4.6.1,
  4.6.3); full-time students no longer need a work-hours floor
- Apply statutory per-day and per-week payment caps and legal non-licensed
  10-hour/day and 50-hour/week caps to provider rates
  (Minn. Stat. 142E.17 subd. 1(f), 2(b))

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Exempt families experiencing homelessness from the authorized-activity
  requirement (CCAP Policy Manual 4.6.9), mirroring MA/SC/AL/KY CCAP via
  is_homeless.
- Floor net self-employment at zero per person so a business loss cannot
  reduce wages or unearned income (Minn. Rules 3400.0170 subp. 4; manual
  6.15.6); split self-employment into its own countable-income source list.
- Cite CCAP Policy Manual 9.9 as the source of the rate-unit hour thresholds.
- Add tests: homelessness exemption, self-employment loss floor (wage, unearned,
  cross-member, and allowed cross-business offset), and the activity term in the
  overall eligibility gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hua7450 hua7450 marked this pull request as ready for review June 17, 2026 03:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Minnesota Child Care Assistance Program (CCAP)

1 participant